﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ElectromagneticCalculation
{
    //信号处理的相关算法
    public static class RawProcess
    {
        /// <summary>
        /// 数据平滑
        /// </summary>
        /// <param name="data">原始数据</param>
        /// <param name="windowSize">窗口值</param>
        /// <returns>处理后的数据</returns>
        public static double[] SmoothData(double[] data, int windowSize)
        {
            double[] smoothedData = new double[data.Length];

            for (int i = 0; i < data.Length; i++)
            {
                int start = Math.Max(0, i - windowSize / 2);
                int end = Math.Min(data.Length - 1, i + windowSize / 2);

                double sum = 0;
                for (int j = start; j <= end; j++)
                {
                    sum += data[j];
                }

                smoothedData[i] = sum / (end - start + 1);
            }

            return smoothedData;
        }

        /// <summary>
        /// 归一化计算
        /// </summary>
        /// <param name="values">原始值</param>
        /// <returns>处理后的值</returns>
        public static double[] Normalize(double[] values)
        {
            double min = values.Min();
            double max = values.Max();
            double range = max - min;

            double[] normalizedValues = new double[values.Length];

            for(int i=0; i<values.Length; i++)
            {
                double normalizedValue = (values[i] - min) / range;
                normalizedValues[i]=normalizedValue;
            }
            return normalizedValues;
        }

        /// <summary>
        /// 平移
        /// </summary>
        /// <param name="values">原始值</param>
        /// <param name="increment">平移值</param>
        /// <returns>平移后的值</returns>
        public static double[] Translate(double[] values, double increment)
        {
            double[] NewValues = new double[values.Length];
            for (int i = 0; i < values.Length; i++)
            {
                NewValues[i] = values[i]+ increment;
            }
            return NewValues;
        }

        /// <summary>
        /// 计算标准差
        /// </summary>
        /// <param name="data">原始数据</param>
        /// <returns>标准差的值</returns>
        public static double CalculateStandardDeviation(double[] data)
        {
            double mean = data.Average();
            double sumOfSquares = data.Sum(x => Math.Pow(x - mean, 2));
            double variance = sumOfSquares / data.Length;
            double stdDev = Math.Sqrt(variance);

            return stdDev;
        }

        /// <summary>
        /// 剔除坏值
        /// </summary>
        /// <param name="values">原始值</param>
        /// <param name="threshold">阈值</param>
        /// <returns>剔除后的值</returns>
        public static double[] Eliminate(double[] values, double threshold)
        {
            double[] NewValues = new double[values.Length];

            double mean = values.Average();
            double stdDev = CalculateStandardDeviation(values);

            for (int i = 0; i < values.Length; i++)
            {
                if (Math.Abs(values[i] - mean) <= threshold * stdDev)
                {
                    NewValues[i] = values[i];
                }
                else
                {
                    //创建一个合理值
                    NewValues[i] = threshold * stdDev + mean;
                }
            }


            return NewValues;
        }

        public static double[] GetArray<T>(List<T> Datas,Func<T,double> Selector)
        {
            if(Datas==null)
            {
                throw new ArgumentNullException();
            }
            if(Selector==null)
            {
                throw new ArgumentNullException();
            }
            if(Datas.Count==0)
            {
                throw new Exception("datas count is zero！");
            }
            double[] temp = new double[Datas.Count];
            for(int i = 0;i < Datas.Count;i++)
            {
                temp[i] = Selector(Datas[i]);
            }
            return temp;
        }

        public static void SetArray<T>(List<T> Datas,double[] NewValues, Action<T,double> Selector)
        {
            if (Datas == null)
            {
                throw new ArgumentNullException();
            }
            if (Selector == null)
            {
                throw new ArgumentNullException();
            }
            if(NewValues== null)
            {
                throw new ArgumentNullException();
            }
            if(Datas.Count!=NewValues.Length)
            {
                throw new Exception("datas count and newvalues count not equality！");
            }
            int Count=Math.Min(Datas.Count, NewValues.Length);
            for(int i = 0; i < Count; i++)
            {
                Selector(Datas[i], NewValues[i]);
            }

        }
    }
}
